<?php

namespace App\Http\Controllers\Admin\Transport;

use App\Exports\OrderExport;
use App\Http\Controllers\Controller;
use App\Http\Requests\Transport\OrderRequest;
use App\Imports\OrderImport;
use App\Models\base\AccountModel;
use App\Models\CustomerModel;
use App\Models\DictionaryModel;
use App\Models\OrderModel;
use App\Models\OrderNodeLogModel;
use App\Models\OrderReceiveModel;
use App\Models\OrderVolumeModel;
use App\Models\TakeOrderModel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;

class Order extends Controller
{
    use OrderRequest;

    public function list(Request $request) {
        $page = $request->input('page', 1);
        $limit = $request->input('limit', 20);
        $keyword = $request->input('keyword', '');
        $goods_attr = $request->input('goods_attr', '');
        $destination = $request->input('des_country_id', '');
        $clearance_mode = $request->input('clearance_mode', '');
//        $customer_type_id = $request->input('customer_type', '');
        $customer_id = $request->input('customer_id', '');
        $is_clearance = $request->input('is_clearance', '');
        $status = $request->input('status', '');
        $is_problem = $request->input('is_problem', '');
        $is_abnormal = $request->input('is_abnormal', '');

        $time_type = $request->input('time_type', '');
        $start_time = $request->input('startTime', '');
        $end_time = $request->input('endTime', '');

        $customer_name = $request->input('customer_name', '');

        $query = OrderModel::query()
            ->where('is_child', 0)
            ->with([
                'create_admin', 'take_order_addr', 'customer', 'split_order_addr', 'take_order'
            ])->withCount('split_order_addr');

        if($keyword) {
            $query->where(function($query) use ($keyword) {
                $query->where('sn', 'like', '%' . $keyword . '%')
                    ->orWhereIn('customer_id', function($query) use ($keyword) {
                        $query->select('id')->from((new CustomerModel())->getTable())->where('name', $keyword);
                    })->orWhereIn('take_order_id', function($query) use ($keyword) {
                        $query->select('id')->from((new TakeOrderModel())->getTable())->where('sn', $keyword);
                    });
            });
        }

        if($customer_id) {
            $query->where('customer_id', $customer_id);
        }

        if($customer_name){
            $query = $query->whereIn('customer_id', function($query) use ($customer_name) {
                $query->select('id')->from((new CustomerModel())->getTable())->where('name', 'like', '%' . $customer_name . '%');
            });
        }

        if($goods_attr){
            $query = $query->where('goods_attr', $goods_attr);
        }

        if($destination){
            $query = $query->where('destination', $destination);
        }

        if($clearance_mode){
            $query = $query->where('clearance_mode', $clearance_mode);
        }

        if(is_numeric($is_clearance)){
            $query = $query->where('is_clearance', intval($is_clearance));
        }

        if($status){
            $query = $query->where('status', $status);
        }

        if(is_numeric($is_problem)){
            $query = $query->where('is_issue', intval($is_problem));
        }

        if(is_numeric($is_abnormal)){
            $query = $query->where('is_exception', intval($is_abnormal));
        }
        // 时间类型（预报-pre，确认-confirm，预报出货-pre_out，入库-storage，出库-outstock，抵达-arrive，清关-clearance，签收-signed）
        if($time_type && $start_time && $end_time) {
            switch ($time_type){
                case 'pre':
                    $query->whereBetween('pre_time', [$start_time, $end_time]);
                    break;
                case 'confirm':
                    $query->whereBetween('confirm_time', [$start_time, $end_time]);
                    break;
                case 'pre_out':
                    $query->whereBetween('pre_out_date', [$start_time, $end_time]);
                    break;
                case 'storage':
                    $query->whereBetween('storage_time', [$start_time, $end_time]);
                    break;
                case 'outstock':
                    $query->whereBetween('outstock_time', [$start_time, $end_time]);
                    break;
                case 'arrive':
                    $query->whereBetween('arrive_time', [$start_time, $end_time]);
                    break;
                case 'clearance':
                    $query->whereBetween('clearance_time', [$start_time, $end_time]);
                    break;
                case 'signed':
                    $query->whereBetween('signed_time', [$start_time, $end_time]);
                    break;
                default:
                    break;
            }
        }

        $total = $query->count('id');
        $items = $query
            ->offset(($page-1) * $limit)
            ->limit($limit)
            ->orderBy('id', 'desc')
            ->get();

        $list = $items->map(function($item) {
            $entry_mode_name = DictionaryModel::where('id', $item->entry_mode)->value('name');

            $edit_form = [
                'id' => $item->id,
                'sn' => $item->sn,
                'customer_id' => $item->customer_id,
                'des_country_id' => $item->destination,
                'goods_attr' => $item->goods_attr,
                'clearance_mode' => $item->clearance_mode,
                'pre_weight' => $item->pre_weight,
                'pre_volume' => $item->pre_volume,
                'is_clearance' => $item->is_clearance,
                'pre_out_date' => $item->pre_out_date,
                'big_pkgs' => $item->big_pkgs,
                'small_pkgs' => $item->small_pkgs,
                'packages' => array_filter(explode(',', $item->packages)),
                'bubble_weight' => $item->bubble_weight,
                // 'rule1' => '',
                // 'rule2' => '',
                'entry_mode' => $item->entry_mode,
                'ship_info' => $item->ship_info,
                'clearance_list' => $item->clearance_list,
                'take_order' => $item->take_order_addr,
                'split_order' => $item->split_order_addr,
                'des_city_id' => $item->des_city_id
            ];


            $packages_name = DictionaryModel::whereIn('id', explode(',', $item->packages))
                    ->pluck('name');

            if($item->children_nums > 0){
                $children = OrderModel::where('father_order_id', $item->id)->select('id', 'sn', 'big_pkgs', 'storage_weight')->get();
            }else{
                $children = [];
            }

            $res = [
                'id' => $item->id,
                'sn' => $item->sn,
                'customer_name' => $item->customer->name ?? '',
                'customer_type' => $item->customer->customer_type->name ?? '',
                'take_order_sn' => $item->take_order->sn ?? '',
                'split_order_addr' => $item->split_order_addr_count,
                'status' => $item->status,
                'status_name' => OrderModel::STATUS_MAPS[$item->status] ?? '',
                'big_pkgs' => $item->big_pkgs,
                'storage_big_pkgs' => $item->storage_big_pkgs,
                'pre_out_date' => $item->pre_out_date,
                'des_country_id' => $item->destination,
                'des_country_name' => $item->destination,
                'goods_attr' => $item->goods_attr,
                'goods_attr_name' => OrderModel::GOODS_ATTR_MAPS[$item->goods_attr] ?? '',
                'clearance_mode' => $item->clearance_mode,
                'clearance_mode_name' => OrderModel::CLEARANCE_MODE_MAPS[$item->clearance_mode] ?? '',
                'is_clearance' => $item->is_clearance,
                'pre_weight' => $item->pre_weight,
                'pre_volume' => $item->pre_volume,
                'pre_volume_weight' => round($item->pre_volume * 166.67, 2),
                'volume_ratio' => round($item->pre_weight != 0 ? ($item->pre_volume * 166.67) / $item->pre_weight : 0, 2),
                'storage_weight' => $item->storage_weight > 0 ? $item->storage_weight : '',
                'storage_volume' => $item->storage_volume,
                'packages' => array_filter(explode(',', $item->packages)),
                'packages_name' => $packages_name,
                'warehouse' => $item->place?->warehouse?->name ?? '',
                'is_issue' => $item->is_issue,
                'is_exception' => $item->is_exception,
                'pre_time' => $item->pre_time,
                'confirm_time' => $item->confirm_time,
                'storage_time' => $item->storage_time,
                'outstock_time' => $item->outstock_time,
                'arrive_time' => $item->arrive_time,
                'clearance_time' => $item->clearance_time,
                'signed_time' => $item->signed_time,
                'edit_form' => $edit_form,
                'enter_mode' => $item->entry_mode,
                'entry_mode_name' => $entry_mode_name,
                'car_number' => $item->car_number,
                'children' => $children,

            ];
            return $res;
        });

        return $this->success(['list' => $list, 'total' => $total]);
    }

    //预报下单
    public function preorder(Request $request){
        $auth = $request->get('auth');
        $params = $request->all();
        $id = intval($request->input('id', 0));

        $check_res = self::preorder_check($params);
        if($check_res->faild){
            return $this->error($check_res->err);
        }

        if(!$params['des_country_id']){
            return $this->error('请选择目的地');
        }

        $is_new = 0;
        if($id) {
            $model = OrderModel::find($id);
            if(!$model) {
                return $this->error('入仓单不存在');
            }

            //只有预报状态能编辑
            if($model->status != OrderModel::STATUS_PREORDER) {
                return $this->error('只有预报状态能编辑');
            }

             $take_order = $model->take_order_addr;
            if(!$take_order){
                $take_order = new OrderReceiveModel();
            }
        } else {
            $is_new = 1;
            $model = new OrderModel();
            $model->sn = trim($params['rule1']??'') . trim($params['des_country_id']??'') . date('ymd') . get_order_sn() . trim($params['suffix']??'');
            $model->status = OrderModel::STATUS_PREORDER;
            $model->customer_status = OrderModel::STATUS_PREORDER;
            $model->pre_time = date('Y-m-d H:i:s');

             $take_order = new OrderReceiveModel();

        }

        $packages = $params['packages'] ?? [];
        DB::beginTransaction();
        try {
            $model->customer_id = $params['customer_id'];
//            $model->airport_id = $params['airport_id'];
//            $model->des_city_id = $params['des_city_id'] ?? 0;
            $model->destination = $params['des_country_id'] ?? '';
            $model->goods_attr = $params['goods_attr'];
            $model->clearance_mode = $params['clearance_mode'];
            $model->entry_mode = $params['entry_mode'];
            $model->pre_weight = floatval($params['pre_weight'] ?? 0);
            $model->pre_volume = floatval($params['pre_volume'] ?? 0);
            $model->is_clearance = intval($params['is_clearance'] ?? 0);
            $model->bubble_weight = floatval($params['bubble_weight'] ?? 0);
            $model->pre_out_date = $params['pre_out_date'] ?? null;
            $model->big_pkgs = intval($params['big_pkgs'] ?? 0);
            $model->load_pkgs_surplus = intval($params['big_pkgs'] ?? 0);
            $model->small_pkgs = intval($params['small_pkgs'] ?? 0);
            $model->packages = implode(',', $packages);
            $model->ship_info = $params['ship_info'] ?? '';
            $model->clearance_list = $params['clearance_list'];
            $model->loadless_big_pkgs = intval($params['big_pkgs'] ?? 0);
            $model->created_admin_id = $auth->id;
            $model->car_number = $params['car_number'] ?? '';
            $model->save();

            if($params['take_order']['addr'] != ''){
                $take_order->weight = 0;
                $take_order->nums = 0;
                $take_order->order_id = $model->id;
                $take_order->type = OrderReceiveModel::TAKE_TYPE;
                $take_order->addr = $params['take_order']['addr'];
                $take_order->goods_name = $params['take_order']['goods_name'];
                $take_order->remark = $params['take_order']['remark'] ?? '';
                $take_order->save();
            }


            OrderReceiveModel::where('order_id', $model->id)
                ->where('type', OrderReceiveModel::SPLIT_TYPE)
                ->delete();
            if(isset($params['split_order'])) {
                foreach($params['split_order'] as $item) {
                    $split_order = new OrderReceiveModel();
                    $split_order->weight = $item['weight'];
                    $split_order->nums = $item['nums'];
                    $split_order->order_id = $model->id;
                    $split_order->type = OrderReceiveModel::SPLIT_TYPE;
                    $split_order->addr = $item['addr'];
                    $split_order->goods_name = $item['goods_name'];
                    $split_order->remark = $item['remark'] ?? '';
                    $split_order->save();
                }
            }

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        if($is_new){
            $this->node_log($request, $model->id, '预报下单', date('Y-m-d H:i:s'));
        }

        return $this->success();
    }

    //确认下单
    public function confirm(Request $request){
        $auth = $request->get('auth');
        $params = $request->all();
        $id = intval($request->input('id'));

         $check_res = self::confirm_check($params);
         if($check_res->faild){
              return $this->error($check_res->err);
         }

        if(!$params['des_country_id']){
            return $this->error('请选择目的地');
        }

        if($id) {
            //有预报的单
            $order = OrderModel::find($id);
            if(!$order) {
                return $this->error('入仓单不存在');
            }
            //只有预报状态能确认
            if($order->status != OrderModel::STATUS_PREORDER) {
                return $this->error('只有预报状态能确认');
            }

        } else {
            //新单确认
            $order = new OrderModel();
            $order->sn = trim($params['rule1']??'') . trim($params['rule2']??'') . date('ymd') . get_order_sn() . trim($params['suffix']??'');
        }

        $take_order = $order->take_order_addr;
        if(!$take_order) {
            $take_order = new OrderReceiveModel();
        }

        $packages = $params['packages'] ?? [];
        if(empty($packages)) {
            return $this->error('请选择包装');
        }

        $packages = $params['packages'] ?? [];
        DB::beginTransaction();
        try {
            $order->status = OrderModel::STATUS_CONFIRM;
            $order->customer_status = OrderModel::STATUS_CONFIRM;
            $order->confirm_time = date('Y-m-d H:i:s');
            $order->customer_id = $params['customer_id'];
//            $order->airport_id = $params['airport_id'];
            $order->destination = $params['des_country_id'] ?? '';
            $order->goods_attr = $params['goods_attr'];
            $order->clearance_mode = $params['clearance_mode'];
            $order->entry_mode = $params['entry_mode'];
            $order->pre_weight = floatval($params['pre_weight'] ?? 0);
            $order->pre_volume = floatval($params['pre_volume'] ?? 0);
            $order->is_clearance = intval($params['is_clearance'] ?? 0);
            $order->bubble_weight = floatval($params['bubble_weight'] ?? 0);
            $order->pre_out_date = $params['pre_out_date'] ?? null;
            $order->big_pkgs = intval($params['big_pkgs'] ?? 0);
            $order->small_pkgs = intval($params['small_pkgs'] ?? 0);
            $order->packages = implode(',', $packages);
            $order->load_pkgs_surplus = intval($params['big_pkgs'] ?? 0);
            $order->ship_info = $params['ship_info'] ?? '';
            $order->clearance_list = $params['clearance_list'];
            $order->surplus_weight = floatval($params['pre_weight'] ?? 0);
            $order->loadless_big_pkgs = intval($params['big_pkgs'] ?? 0);
            $order->created_admin_id = $auth->id;
            $order->car_number = $params['car_number'] ?? '';
            $order->save();

            //提单
            $take_order->weight = 0;
            $take_order->nums = 0;
            $take_order->order_id = $order->id;
            $take_order->type = OrderReceiveModel::TAKE_TYPE;
            $take_order->addr = $params['take_order']['addr'];
            $take_order->goods_name = $params['take_order']['goods_name'];
            $take_order->remark = $params['take_order']['remark'] ?? '';
            $take_order->save();

            //分单
            OrderReceiveModel::where('order_id', $order->id)
                ->where('type', OrderReceiveModel::SPLIT_TYPE)
                ->delete();
            if(isset($params['split_order'])) {
                foreach($params['split_order'] as $item) {
                    $split_order = new OrderReceiveModel();
                    $split_order->weight = $item['weight'];
                    $split_order->nums = $item['nums'];
                    $split_order->order_id = $order->id;
                    $split_order->type = OrderReceiveModel::SPLIT_TYPE;
                    $split_order->addr = $item['addr'];
                    $split_order->goods_name = $item['goods_name'];
                    $split_order->remark = $item['remark'] ?? '';
                    $split_order->save();
                }
            }

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        $this->node_log($request, $order->id, '确认下单', date('Y-m-d H:i:s'));

        return $this->success();
    }

    //详情
    public function detail(int $id){
        $order = OrderModel::withCount('split_order_addr')
            ->with([
                'split_order_addr',
                'flight'
            ])->find($id);
        if(!$order) {
            return $this->error('记录不存在');
        }

        $take_receive = OrderReceiveModel::where('order_id', $order->id)
            ->where('type', OrderReceiveModel::TAKE_TYPE)
            ->first();


        $packages_name = DictionaryModel::whereIn('id', explode(',', $order->packages))
                ->pluck('name');

        $entry_mode_name = DictionaryModel::where('id', $order->entry_mode)->value('name');


//        $country_name = $order->airport->country_name ?? '';
//        if($country_name) {
//            $country_name = ' (' . $country_name . ')';
//        }
//        $iata = $order->airport->iata ?? '';

        //入库信息
        $storage_info = OrderVolumeModel::where('order_id', $order->id)->get();
        $storage_info = $storage_info->map(function($item) {
            return $item->len . '*' . $item->width . '*' . $item->height . '/' . $item->nums;
        });

        //排货信息
        $route = $flight_number = $flight_date = '';
        if($order->flight){
            $route = $order->flight->items->map(function($item) {
                return $item->route->code ?? '';
            })->implode(',');
            $flight_number = $order->flight->flight_number ?? '';
            $flight_date = $order->flight->flight_date ?? '';
        }

        $res = [
            'id' => $order->id,
            'sn' => $order->sn,
            'take_order_no' => $order->take_order->sn ?? '',
            'pre_weight' => $order->pre_weight,
            'storage_weight' => $order->storage_weight,
            'split_order_addr_count' => $order->split_order_addr_count ?? 0,
            'status' => OrderModel::STATUS_MAPS[$order->status] ?? '',
            'pre_out_date' => $order->pre_out_date,
            'is_clearance' => $order->is_clearance,
            'des_country' => $order->destination,
//            'des_city' => $order->des_city->name ?? '',
            'goods_attr' => OrderModel::GOODS_ATTR_MAPS[$order->goods_attr] ?? '',
            'clearance_mode' => OrderModel::CLEARANCE_MODE_MAPS[$order->clearance_mode] ?? '',
            'pre_volume' => $order->pre_volume,
            'storage_volume' => $order->storage_volume,
            'packages' => $packages_name,
            'big_pkgs' => $order->big_pkgs,
            'storage_big_pkgs' => $order->storage_big_pkgs,
            'small_pkgs' => $order->small_pkgs,
            'pre_time' => $order->pre_time,
            'confirm_time' => $order->confirm_time,
            'storage_time' => $order->storage_time,
            'outstock_time' => $order->outstock_time,
            'arrive_time' => $order->arrive_time,
            'signed_time' => $order->signed_time,
            'take_receive' => [
                'id' => $take_receive->id ?? '',
                'order_id' => $take_receive->order_id ?? '',
                'sn' => $take_receive->sn ?? '',
                'addr' => $take_receive->addr ?? '',
                'nums' => $order->big_pkgs ?? '',
                'goods_name' => $take_receive->goods_name ?? '',
                'weight' => $order->pre_weight ?? '',
                'remark' => $take_receive->remark ?? '',
            ],
            'split_order' => $order->split_order_addr ?? [],
            'enter_mode' => $entry_mode_name,
            'storage_info' => $storage_info,
            'flight_id' => $order->flight_id ?? '',
            'route' => $route,
            'flight_number' => $flight_number,
            'flight_date' => $flight_date,
        ];

        return $this->success($res);
    }

    public function delete(int $id){
        $model = AccountModel::find($id);
        if(!$model) {
            return $this->error('记录不存在');
        }
        $model->delete();
        return $this->success();
    }

    //导出
    public function export(Request $request){
//        $keyword = $request->input('keyword', '');
//        $goods_attr = $request->input('goods_attr', '');
//        $des_country_id = $request->input('des_country_name', '');
//        $clearance_mode = $request->input('clearance_mode', '');
//        $customer_type_id = $request->input('customer_type', '');
//        $is_clearance = $request->input('is_clearance', '');
//        $status = $request->input('status', '');
//        $is_problem = $request->input('is_problem', '');
//        $is_abnormal = $request->input('is_abnormal', '');
//
//        $time_type = $request->input('time_type', '');
//        $start_time = $request->input('startTime', '');
//        $end_time = $request->input('endTime', '');
//
//        $query = OrderModel::query()
//            ->with([
//                'create_admin', 'take_order_addr', 'customer', 'split_order_addr', 'take_order'
//            ])->withCount('split_order_addr');
//
//        if($keyword) {
//            $query->where('sn', 'like', "%{$keyword}%");
//        }
//
//        if($customer_type_id) {
//            $query->whereIn('customer_id', function($query) use ($customer_type_id) {
//                $query->select('id')->from((new CustomerModel())->getTable())->where('customer_type_id', $customer_type_id);
//            });
//        }
//
//        if($goods_attr){
//            $query = $query->where('goods_attr', $goods_attr);
//        }
//
//        if($des_country_id){
//            $query = $query->where('des_country_id', $des_country_id);
//        }
//
//        if($clearance_mode){
//            $query = $query->where('clearance_mode', $clearance_mode);
//        }
//
//        if(is_numeric($is_clearance)){
//            $query = $query->where('is_clearance', intval($is_clearance));
//        }
//
//        if($status){
//            $query = $query->where('status', $status);
//        }
//
//        if(is_numeric($is_problem)){
//            $query = $query->where('is_issue', intval($is_problem));
//        }
//
//        if(is_numeric($is_abnormal)){
//            $query = $query->where('is_exception', intval($is_abnormal));
//        }
//        // 时间类型（预报-pre，确认-confirm，预报出货-pre_out，入库-storage，出库-outstock，抵达-arrive，清关-clearance，签收-signed）
//        if($time_type && $start_time && $end_time) {
//            switch ($time_type){
//                case 'pre':
//                    $query->whereBetween('pre_time', [$start_time, $end_time]);
//                    break;
//                case 'confirm':
//                    $query->whereBetween('confirm_time', [$start_time, $end_time]);
//                    break;
//                case 'pre_out':
//                    $query->whereBetween('pre_out_date', [$start_time, $end_time]);
//                    break;
//                case 'storage':
//                    $query->whereBetween('storage_time', [$start_time, $end_time]);
//                    break;
//                case 'outstock':
//                    $query->whereBetween('outstock_time', [$start_time, $end_time]);
//                    break;
//                case 'arrive':
//                    $query->whereBetween('arrive_time', [$start_time, $end_time]);
//                    break;
//                case 'clearance':
//                    $query->whereBetween('clearance_time', [$start_time, $end_time]);
//                    break;
//                case 'signed':
//                    $query->whereBetween('signed_time', [$start_time, $end_time]);
//                    break;
//                default:
//                    break;
//            }
//        }
//
//        $items = $query
//            ->orderBy('id', 'desc')
//            ->get();

        $ids = $request->input('ids', []);
        $items = OrderModel::query()->whereIn('id', $ids)->get();

        $list = $items->map(function($item) {

            $packages_name = DictionaryModel::whereIn('id', explode(',', $item->packages))
                ->pluck('name')->implode('+');

            $volume_ratio = $item->pre_weight != 0 ? ($item->pre_volume * 166.67) / $item->pre_weight : 0;
            $res = [
                'customer_name' => $item->customer->name ?? '',
                'customer_type' => $item->customer->customer_type->name ?? '',
                'sn' => $item->sn,
                'take_order_sn' => $item->take_order->sn ?? '',
                'split_order_addr' => $item->split_order_addr_count,
                'status_name' => OrderModel::STATUS_MAPS[$item->status] ?? '',
                'big_pkgs' => $item->big_pkgs,
                'pre_out_date' => $item->pre_out_date,
                'des_country_name' => $item->airport->country_name ?? '',
                'goods_attr_name' => OrderModel::GOODS_ATTR_MAPS[$item->goods_attr] ?? '',
                'clearance_mode_name' => OrderModel::CLEARANCE_MODE_MAPS[$item->clearance_mode] ?? '',
                'is_clearance' => $item->is_clearance == 0 ? '否' : '是',
                'pre_weight' => $item->pre_weight,
                'pre_volume' => $item->pre_volume,
                'volume_ratio' => $volume_ratio,
                'storage_weight' => $item->storage_weight,
                'storage_volume' => $item->storage_volume,
                'warehouse' => $item->place?->warehouse?->name ?? '',
                'pre_volume_weight' => $item->pre_volume * 166.67,
                'ratio_weight' => $volume_ratio * $item->pre_weight,
                'packages_name' => $packages_name,
                'pre_time' => $item->pre_time,
                'confirm_time' => $item->confirm_time,
                'storage_time' => $item->storage_time,
                'outstock_time' => $item->outstock_time,
                'arrive_time' => $item->arrive_time,
                'clearance_time' => $item->clearance_time,
                'signed_time' => $item->signed_time,
            ];
            return $res;
        });

        return Excel::download(new OrderExport(collect($list)), 'orders.xlsx');
    }

    //删除
    public function del(Request $request, $id) {
        $order = OrderModel::find($id);
        if (!$order) {
            return $this->success();
        }
        if($order->status > 4) {
            return $this->error('当前状态不能删除');
        }

        DB::beginTransaction();
        try{

            if($order->split_father_id){
                $order_father = OrderModel::find($order->split_father_id);
                $order_father->storage_weight = $order_father->storage_weight + $order->storage_weight;
                $order_father->big_pkgs = $order_father->big_pkgs + $order->big_pkgs;
                $order_father->save();
            }

            $order->delete();

            DB::commit();
        } catch(\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }


        return $this->success();
    }

    //导入
    public function import(Request $request) {
        $auth = $request->get('auth');
        $file = $request->file('file');
        if(!$file) {
            return $this->error('请选择文件');
        }

        $import = new OrderImport();
        Excel::import($import, $file);

        if(!empty($import->error)) {
            return $this->success([
                'errors' => $import->error
            ]);
        }

        DB::beginTransaction();
        try {
            foreach($import->result as $params) {
                $customer = CustomerModel::find($params['customer_id']);

                $model = new OrderModel();
                $model->sn = ($customer->name_en ?? '') . $params['destination'] . date('ymd') . get_order_sn();
                $model->status = OrderModel::STATUS_PREORDER;
                $model->pre_time = date('Y-m-d H:i:s');

                $model->customer_id = $params['customer_id'];
                $model->destination = $params['destination'];
                $model->goods_attr = $params['goods_attr'];
                $model->clearance_mode = $params['clearance_mode'];
                $model->entry_mode = $params['entry_mode'];
                $model->pre_weight = floatval($params['pre_weight'] ?? 0);
                $model->pre_volume = floatval($params['pre_volume'] ?? 0);
                $model->is_clearance = intval($params['is_clearance'] ?? 0);
                $model->bubble_weight = floatval($params['bubble_weight'] ?? 0);
                $model->pre_out_date = $params['pre_out_date'] ?? null;
                $model->big_pkgs = intval($params['big_pkgs'] ?? 0);
                $model->load_pkgs_surplus = intval($params['big_pkgs'] ?? 0);
                $model->small_pkgs = intval($params['small_pkgs'] ?? 0);
                $model->packages = implode(',', $params['packages'] ?? []);
                $model->ship_info = $params['ship_info'] ?? '';
                $model->loadless_big_pkgs = intval($params['big_pkgs'] ?? 0);
                $model->created_admin_id = $auth->id;
                $model->save();
            }
            DB::commit();
        } catch(\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        return $this->success();

    }


    //集运入库
    public function storage(Request $request) {
        $params = $request->all();

        $validator = Validator::make($params, [
            'id' => 'required',
            'storage_weight' => 'required|numeric',
//            'storage_time' => 'required',
//            'storage_volume' => 'required|numeric',
            'place_id' => 'required|integer',
            'volumes' => 'array'
        ], [
            'id.required' => '请选择入仓单',
            'storage_weight.required' => '请填写入库重量',
            'storage_weight.numeric' => '入库重量必须为数字',
            'storage_time.required' => '请选择入库时间',
            'storage_volume.required' => '请填写入库体积',
            'storage_volume.numeric' => '入库体积必须为数字',
            'place_id.required' => '请选择库位',
            'volumes.required' => '请填写体积信息',
            'volumes.array' => '体积信息必须为数组'
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $order = OrderModel::find($params['id']);
        if (!$order) {
            return $this->error('入仓单不存在');
        }

        foreach($params['volumes'] as $volume)  {
            $validator = Validator::make($volume, [
                'len' => 'required|numeric',
                'width' => 'required|numeric',
                'height' => 'required|numeric',
                'nums' => 'required|integer',
            ], [
                'len.required' => '请填写长度',
                'width.required' => '请填写宽度',
                'height.required' => '请填写高度',
                'len.numeric' => '长度必须为数字',
                'width.numeric' => '宽度必须为数字',
                'height.numeric' => '高度必须为数字',
                'nums.required' => '请填写数量',
                'nums.integer' => '数量必须为整数'
            ]);

            if ($validator->fails()) {
                return $this->error($validator->errors()->first());
            }
        }

        try{
            DB::transaction(function () use ($params, $order) {
                $order->status = OrderModel::STATUS_STORAGE;
                $order->customer_status = OrderModel::STATUS_STORAGE;
                $order->storage_weight = $params['storage_weight'];
                $order->storage_volume = $params['storage_volume'] ?? 0;
                $order->place_id = $params['place_id'];
                $order->loadless_weight = $params['storage_weight'];
//                $order->storage_time = date('Y-m-d H:i:s');
                $order->storage_time = $params['storage_time'] ?? null;
                $order->surplus_weight = $params['storage_weight'];
                $order->save();

//                $storage_volume = 0;
                $storage_big_pkgs = 0;

                $find_volume = OrderVolumeModel::where('order_id', $order->id)->get();

                if($find_volume) {
                    OrderVolumeModel::where('order_id', $order->id)->delete();
                }
                foreach($params['volumes'] as $volume) {
                    $model = new OrderVolumeModel();
                    $model->order_id = $order->id;
                    $model->len = $volume['len'];
                    $model->width = $volume['width'];
                    $model->height = $volume['height'];
                    $model->nums = $volume['nums'];
                    $model->save();

//                    $storage_volume += $volume['len'] * $volume['width'] * $volume['height'] * $volume['nums'];
                    $storage_big_pkgs += $volume['nums'];
                }

//                $order->storage_volume = round($storage_volume / 1000000, 2);
                $order->storage_big_pkgs = $storage_big_pkgs;
                $order->save();
            });
        } catch(\Exception $e) {
            return $this->error($e->getMessage());
        }

        $this->node_log($request, $order->id, '入库', $params['storage_time'] ?? null );

        return $this->success();

    }

    //获取集运入库信息
    public function storage_info(Request $request) {
        $id = $request->input('id',  '');

        $order = OrderModel::find($id);

        if(!$order){
            return $this->error('入仓单不存在');
        }

        $volumes = OrderVolumeModel::where('order_id', $id)->get();

        if(!$volumes){
            $volumes = [];
        }else{
            $volumes = $volumes->toArray();
        }

        $volumes_text = array_map(function ($volume) {
            $len = rtrim(rtrim(strval($volume['len']), '0'), '.');
            $width = rtrim(rtrim(strval($volume['width']), '0'), '.');
            $height = rtrim(rtrim(strval($volume['height']), '0'), '.');
            return $len . '*' . $width . '*' . $height . '/' . $volume['nums'];
        }, $volumes);

        return $this->success([
            'id' => $id,
            'storage_weight' => $order->storage_weight > 0 ? $order->storage_weight : '',
            'storage_volume' => $order->storage_volume > 0 ? $order->storage_volume : '',
            'storage_time' => $order->storage_time,
            'place_id' => $order->place_id,
            'volumes' => $volumes,
            'volumes_text' => $volumes_text
        ]);
    }

    //分单
    public function split_order(Request $request) {
        $id = $request->input('id',  '');
        $weight = $request->input('weight',  0);
        $nums = $request->input('nums',  0);

        if(!$weight){
            return $this->error('请填写重量');
        }

        if(!$nums){
            return $this->error('请填写数量');
        }

        $order = OrderModel::find($id);
        if(!$order){
            return $this->error('入仓单不存在');
        }

        if($weight >= $order->storage_weight){
            return $this->error('分单重量不能大于入仓单入库重量');
        }
        if($nums >= $order->big_pkgs){
            return $this->error('分单数量不能大于入仓单件数');
        }

        DB::beginTransaction();
        try{
            $new_order = $order->toArray();
            unset($new_order['id']);
            $new_order['sn'] = $order->sn . '_' . $order->split_times + 1;
            $new_order['split_father_id'] = $order->id;
            $new_order['storage_weight'] = $weight;
            $new_order['big_pkgs'] = $nums;
            $new_order['cargo_status'] = OrderModel::CARGO_STATUS_NO;
            $new_order['created_at'] = date('Y-m-d H:i:s');

           //分单配载
           if($new_order['is_load'] == 1){
               if($nums <= $new_order['load_pkgs']){
                   $new_order['is_load'] = 2;
                   $new_order['load_pkgs'] = $nums;
                   $new_order['load_weight'] = $weight;

                   $order->load_pkgs = $order->load_pkgs - $nums;
                   $order->load_weight = $order->load_weight - $weight;
               }else{
                   $new_order['load_pkgs'] = $order->load_pkgs;
                   $new_order['load_weight'] = $order->load_weight;
                   $order->load_pkgs = 0;
                   $order->load_weight = 0;
               }
           }
            OrderModel::insert($new_order);

            $order->storage_weight = $order->storage_weight - $weight;
            $order->big_pkgs = $order->big_pkgs - $nums;
            $order->split_times = $order->split_times + 1;
            $order->save();

            if($order->cargo_status > 2){
                $take_order = TakeOrderModel::find($order->take_order_id);
                if($take_order){
                    $take_order->big_pkgs = $take_order->big_pkgs - $nums;
                    $take_order->save();
                }
            }

            DB::commit();
        } catch(\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        return $this->success();

    }


    /**
     * 报关
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|void
     */
    public function declare(Request $request)
    {
        $ids = $request->input('ids', []);
        $time = $request->input('time', '');

        if(!$time){
            return $this->error('请选择时间');
        }


        $orders = OrderModel::find($ids);

        if(!$orders){
            return $this->error('入仓单不存在');
        }

        $status = $orders->pluck('status')->unique();
        if($status->count() > 1){
            return $this->error('节点状态不一致');
        }

        $entry_mode = $orders->first()->entry_mode;

        if(!in_array($entry_mode, OrderModel::HK_ENTER_MODE) && $status->first() != OrderModel::STATUS_OUTSTOCK){
            return $this->error('节点状态为出库才能报关');
        }

        $max_out_time = $orders->max('out_time');

       if($time && $time < $max_out_time){
          return $this->error('报关时间不能小于出库时间');
       }

        DB::beginTransaction();
        try {

            foreach ($orders as $order){
                $order->declare_time = $time;
                $order->status = OrderModel::STATUS_DECLARE;
                $order->save();

                $this->node_log($request, $order->id, '报关', $time);
            }

            DB::commit();

        } catch (\Exception $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }



        return $this->success();
    }

    /**
     * 查验
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function check(Request $request)
    {
        $ids = $request->input('ids', []);
        $time = $request->input('time', '');
        if(!$time){
            return $this->error('请选择时间');
        }
        $orders = OrderModel::find($ids);
        if(!$orders){
            return $this->error('入仓单不存在');
        }
        $status = $orders->pluck('status')->unique();
        if($status->count() > 1){
            return $this->error('节点状态不一致');
        }

        $entry_mode = $orders->first()->entry_mode;

        if(!in_array($entry_mode, OrderModel::HK_ENTER_MODE) && $status->first() != OrderModel::STATUS_DECLARE){
            return $this->error('节点状态为报关才能查验');
        }
        DB::beginTransaction();
        try {
            foreach ($orders as $order){
                $order->check_time = $time;
                $order->status = OrderModel::STATUS_CHECK;
                $order->save();

                $this->node_log($request, $order->id, '查验', $time);
            }
            DB::commit();
        } catch (\Exception $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }


        return $this->success();
    }

    /**
     * 放行
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function pass(Request $request)
    {
        $ids = $request->input('ids', []);
        $time = $request->input('time', '');
        if(!$time){
            return $this->error('请选择时间');
        }
        $orders = OrderModel::find($ids);
        if(!$orders){
            return $this->error('入仓单不存在');
        }
        $status = $orders->pluck('status')->unique();
        if($status->count() > 1){
            return $this->error('节点状态不一致');
        }

        $entry_mode = $orders->first()->entry_mode;

        if(!in_array($entry_mode, OrderModel::HK_ENTER_MODE) && $status->first() != OrderModel::STATUS_CHECK && $status->first() != OrderModel::STATUS_DECLARE){
            return $this->error('节点状态为报关或查验才能放行');
        }

        $max_declare_time = $orders->max('declare_time');
        if($time && $time < $max_declare_time){
           return  $this->error('放行时间不能小于报关时间');
        }

        DB::beginTransaction();
        try {
            foreach ($orders as $order){
                $order->pass_time = $time;
                $order->status = OrderModel::STATUS_PASS;
                $order->save();

                $this->node_log($request, $order->id, '放行', $time);
            }
            DB::commit();
        } catch (\Exception $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }


        return $this->success();
    }

    /**
     * 节点日志
     * @param $request
     * @param $order_id
     * @param $name
     * @param $time
     * @return void
     */
    public function node_log($request, $order_id, $name, $time)
    {
        $auth = $request->get('auth');

        $log = new OrderNodeLogModel();
        $log->order_id = $order_id;
        $log->name = $name;
        $log->time = $time;
        $log->url = $request->url();
        $log->created_admin_id = $auth->id;
        $log->save();

    }

}
